import pygame
from setting import *
from player import *
import random
from os import path
vec=pygame.math.Vector2
HEIGHT=730
FPS=60
FONT_MANE='arial' #is a kind of font(字体）
WHITE=(255,255,255)
BLACK=(0,0,0)
RED=(255,0,0)
GREEN=(0,255,0)
BLUE=(0,0,255)
YELLO=(255,255,0)
LITTLEBLUE=(70,163,142)
PLAYER_FRICTION_X=-0.055
PLAYER_FRICTION_Y=-0.01
PLAYER_ACC=0.95
CENTER=(WIDTH/2,HEIGHT/2)
SPRITE_SHEET='spritesheet_jumper.png'
import pygame
from setting import *
import random
vec=pygame.math.Vector2
class Player(pygame.sprite.Sprite):
    def __init__(self,game):
        self.game=game
        #self.groups=self.game.all_sprite
        pygame.sprite.Sprite.__init__(self)
        self.image=pygame.image.load('huaqiang.png')
        self.image=pygame.transform.scale(self.image,(150,150))
        self.image.set_colorkey(WHITE)
        #self.image=pygame.image.load(self.standing_frames[0])
        self.image.set_colorkey(LITTLEBLUE)
        self.image=pygame.transform.scale(self.image,(72,100))
        self.rect=self.image.get_rect()
        self.rect.center=(WIDTH/2,HEIGHT/2)
        self.pos=vec(WIDTH/2,HEIGHT/2)
        self.vel=vec(0,0)
        self.acc=vec(0,0)
        self.death=0
        self.height=0
        self.walking=False
        self.jumping=False
        self.current_frame=0
        self.last_update=0
        self.mask=pygame.mask.from_surface(self.image)
    def load_images(self):
        self.standing_frames=['rabit_stoop.png','rabit_stand_still.png']
        self.walk_frames_right=['rabit_right_stand.png','rabit_right_walk.png']
        self.walk_frames_left=['rabit_left_stand.png','rabit_left_walk.png']
        self.walk_frames_list=[]
        '''for frame in self.walk_frames_right:
            self.walk_frames_list.append(pygame.transform.flip(frame,True,False))'''
    def update(self):
        self.acc=vec(0,1)
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.acc.x= -PLAYER_ACC
        if keys[pygame.K_RIGHT]:
            self.acc.x = PLAYER_ACC
        #only on the platform can we jump
        #and increase our vel meet the platform
        self.rect.y += 5
        hits = pygame.sprite.spritecollide(self, self.game.platforms, False)
        for i in hits:
            if i.rect.y>hits[0].rect.y:
                hits[0]=i
        self.rect.y -= 5
        if hits:
            if pygame.K_DOWN:
             if keys[pygame.K_UP]:
                     self.vel.y = -23
                     self.game.jump_sound.play()
        if keys[pygame.K_DOWN]:
            self.acc.y = PLAYER_ACC
        self.acc.x+=self.vel.x*PLAYER_FRICTION_X
        self.acc.y+=self.vel.y*PLAYER_FRICTION_Y
        self.vel+=self.acc
        if self.vel.y<-30:
            self.vel.y=-30
        self.pos+=self.vel+self.acc*0.5
        if self.pos.x<0:
            self.pos.x=WIDTH
        if self.pos.x>WIDTH:
            self.pos.x=0
        '''if self.pos.y<0:
            self.pos.y=HEIGHT'''
        if self.pos.y>HEIGHT+50:
            self.death=1
        self.rect.midbottom=self.pos
class Platform(pygame.sprite.Sprite):
    def __init__(self,x,y,game):
        self.game=game
        #self.groups = game.all_sprite, game.platforms
        pygame.sprite.Sprite.__init__(self)
        self.image=pygame.image.load('moto_bike.png')
        self.image=pygame.transform.scale(self.image,(200,80))
        self.image.set_colorkey(LITTLEBLUE)
        self.rect=self.image.get_rect()
        self.rect.x=x
        self.rect.y=y
        if 7<random.randrange(1,9):
             self.powerup = Pow(self)
             self.game.all_sprite.add(self.powerup)
             self.game.powerups.add(self.powerup)
        if 7<random.randrange(1,9):
             self.enemy = Enemy(self)
             self.game.all_sprite.add(self.enemy)
             self.game.enemies.add(self.enemy)
'''class Spritesheet:
    #utility class for loading and parsing spritesheets
    def __init__(self,filename):
        self.spritesheet=pygame.image.load(filename)
    def get_image(self,x,y,width,height):
        #grab image out of a larger image spritesheet
        image=pygame.Surface((width,height))
        image.blit(self.spritesheet,(x,y,width,height))
        return image'''
class Pow(pygame.sprite.Sprite):
    def __init__(self,plat):
        #self.groups=self.game.self.all_sprite,self.game.powerups
        pygame.sprite.Sprite.__init__(self)
        self.plat=plat
        self.image=pygame.image.load('water_meleon.png')
        self.image = pygame.transform.scale(self.image, (100, 100))
        self.image.set_colorkey(LITTLEBLUE)
        self.rect=self.image.get_rect()
        self.rect.centerx=self.plat.rect.centerx
        self.rect.bottom=self.plat.rect.top+5
class Enemy(pygame.sprite.Sprite):
    def __init__(self,plat):
        #self.groups=self.game.self.all_sprite,self.game.powerups
        pygame.sprite.Sprite.__init__(self)
        self.plat=plat
        self.image=pygame.image.load('watermelon_saler.png')
        self.image=pygame.transform.scale(self.image,(120,120))
        self.image.set_colorkey((255,255,255))
        self.image.set_colorkey(LITTLEBLUE)
        self.rect=self.image.get_rect()
        self.rect.centerx=self.plat.rect.centerx
        self.rect.bottom=self.plat.rect.top-5
        self.now = pygame.time.get_ticks()
        self.speed_x=5
        self.acc_y=0.5
        self.vel_y=0
        self.pos_y=self.rect.bottom
        self.mask=pygame.mask.from_surface(self.image)
    def update(self):
        self.rect.x+=self.speed_x
        if self.rect.x>WIDTH:
            self.speed_x=-4
        if self.rect.x<0:
            self.speed_x=4
        '''self.vel_y+=self.acc_y
        self.pos_y+=self.vel_y+0.5*self.acc_y
        if self.vel_y<-3:
            self.acc_y=0.5
        if self.vel_y>3:
            self.acc_y=-0.5
        self.rect.bottom=self.pos_y'''

PLATFORM_LIST=[(0,0.9*HEIGHT),
          (WIDTH/2-30,HEIGHT*3/4),
          (800,HEIGHT-350),
          (175,200)]
class Cloud(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image=pygame.image.load(random.choice(['cloud_2.png','cloud.png']))
        self.image=pygame.transform.scale(self.image,(random.randrange(75,150),random.randrange(37,70)))
        self.rect=self.image.get_rect()
        self.rect.center=(random.randrange(0,WIDTH),random.randrange(-1000,500))
class Game():
    def __init__(self):
        pygame.init()
        pygame.mixer.init()
        self.jump_sound=pygame.mixer.Sound('one_man_to_buy.mp3')
        #self.death_sound=pygame.mixer.Sound('death_sound.mp3')
        self.falling_sound=pygame.mixer.Sound('kill_a_man.mp3')
        #pygame.mixer.music.load('back_music.mp3')
        #pygame.mixer.music.play(loops=-1)
        self.screen=pygame.display.set_mode((WIDTH,HEIGHT))
        title=pygame.display.set_caption('PLANE MOVING')
        self.screen.fill(WHITE)
        self.clock=pygame.time.Clock()
        self.all_sprite = pygame.sprite.Group()
        self.player = Player(self)
        self.all_sprite.add(self.player)
        self.platforms=pygame.sprite.Group()
        self.powerups=pygame.sprite.Group()
        self.enemies=pygame.sprite.Group()
        self.clouds=pygame.sprite.Group()
        self.players=pygame.sprite.Group()
        self.players.add(self.player)
        #self.all_sprite.add(self.cloud)
        self.font_name=pygame.font.match_font(FONT_MANE)
        '''self.platform=Platform(0,0.8*HEIGHT,WIDTH,20)
        self.platforms.add(self.platform)
        self.all_sprite.add(self.platform)
        p2=Platform(WIDTH/2,HEIGHT*0.6,100,20)
        self.all_sprite.add(p2)
        self.platforms.add(p2)'''
        for plat in PLATFORM_LIST:
            self.platform=Platform(plat[0],plat[1],self)
            self.platforms.add(self.platform)
            self.all_sprite.add(self.platform)
        self.running=True
        self.playing=True
        self.waiting=True
        self.draw_screen()
        self.score=0
    def update(self):
        self.events()
        self.draw()
        hits=pygame.sprite.spritecollide(self.player,self.platforms,False)
        #if self.player.vel.y>0:
        if hits:
            if self.player.vel.y>=0:
            #if self.player.pos.x<hits[0].rect.right and \
                    #self.player.pos.x> hits[0].rect.left:
               if self.player.pos.y<hits[0].rect.bottom+50:
                # self.player.vel.y=-self.player.vel.y
                self.player.pos.y = hits[0].rect.top
                self.player.vel.y = 0
                self.player.acc.y = 0
        #scroll the screen
        pow_hit=pygame.sprite.spritecollide(self.player,self.powerups,True)
        if pow_hit:
            pygame.mixer.Sound('how_much_melon.mp3').play()
            self.player.vel.y=-30
            self.score+=30
        enemy_hit=pygame.sprite.spritecollide(self.player,self.enemies,False,pygame.sprite.collide_mask)
        if self.player.rect.top<HEIGHT*0.25:
            self.player.rect.y+=max(abs(self.player.vel.y)*1.3,5)
            #self.player.height+=abs(self.player.vel.y)*0.5
            for platform in self.platforms:
                 platform.rect.y+=max(abs(self.player.vel.y)*1.3,5)
                 if platform.rect.top>=HEIGHT:
                     platform.kill()
                     self.score+=5
            for power in self.powerups:
                 power.rect.y+=max(abs(self.player.vel.y)*1.3,5)
                 if power.rect.top>=HEIGHT:
                     power.kill()
            for enemy in self.enemies:
                 enemy.rect.y+=max(abs(self.player.vel.y)*1.3,5)
                 if enemy.rect.top>=HEIGHT:
                     enemy.kill()
            for cloud in self.clouds:
                cloud.rect.y+=max(abs(self.player.vel.y)*0.2,2)
                if cloud.rect.top >= HEIGHT:
                    cloud.kill()
        while len(self.platforms)<6:
            random_height=random.randrange(-200,-25)
            for platform in self.platforms:
                random_number=random.randrange(-200,-25)
                if abs(platform.rect.y-random_number)>75:
                    random_height=random_number
            p=Platform(random.randrange(0,WIDTH-70),
                       random_height,
                       self)
            self.platforms.add(p)
            self.all_sprite.add(p)
        if  self.player.death==1:
            self.falling_sound.play()
            self.falling_sound.fadeout(2000)
            for sprite in self.all_sprite:
                sprite.rect.y-=max(10,self.player.vel.y)
                if sprite.rect.bottom<0:
                   sprite.kill()
            if len(self.all_sprite)<2:
                with open('PLANE_RECORD','a') as file:
                    file.write(str(self.score)+'\n')
                pygame.mixer.music.fadeout(1000)
                self.draw_death_screen()
                self.playing=False
        if enemy_hit:
            with open('PLANE_RECORD', 'a') as file:
                file.write(str(self.score) + '\n')
            #pygame.mixer.music.fadeout(1000)
            pygame.mixer.Sound('killing.mp3').play()
            self.draw_death_screen()
            self.playing = False
    def animate(self):
        now=pygame.time.get_ticks()

    def events(self):
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                self.running=False
                self.playing=False
            if event.type==pygame.KEYDOWN:
                if event.key==pygame.K_UP:
                    pass
    def draw(self):
        self.all_sprite.update()
        self.screen.fill(LITTLEBLUE)
        if len(self.clouds)<6:
            self.cloud = Cloud()
            self.clouds.add(self.cloud)
        self.clouds.draw(self.screen)
        self.draw_text(str(self.score), 33, BLACK, WIDTH / 2, 15)
        self.draw_time()
        keys=pygame.key.get_pressed()
        self.now=pygame.time.get_ticks()
        '''if keys[pygame.K_RIGHT]:
            if 250<= self.now % 500 < 500:
                self.player.image=pygame.image.load('rabit_right_walk.png')
            elif 0 <= self.now % 500< 250:
                self.player.image=pygame.image.load('rabit_right_stand.png')
        elif keys[pygame.K_LEFT]:
            if 250 <= self.now % 500 < 500:
                self.player.image=pygame.image.load('rabit_left_walk.png')
            elif 0 <= self.now % 500 < 250:
                self.player.image=pygame.image.load('rabit_left_stand.png')
        else:
            if 250 <= self.now % 500 < 500:
               self.player.image=pygame.image.load('rabit_stand_still.png')
            elif 0 <= self.now % 500 < 250:
                self.player.image=pygame.image.load('rabit_stoop.png')
        if 500<=self.now%1000<1000:
            for enemy in self.enemies:
                enemy.image=pygame.image.load('enemy_jump.png')
        else:
            for enemy in self.enemies:
                enemy.image=pygame.image.load('enemy_stand.png')'''
        self.screen.blit(self.player.image,self.player.rect)
        self.platforms.draw(self.screen)
        self.all_sprite.draw(self.screen)
        self.players.draw(self.screen)
        pygame.display.flip()
    def draw_text(self,text,size,color,x,y):
        font=pygame.font.Font(self.font_name,size)#create a font object(the size =height)(self.font_name decide a kind of font,none means default font)
        text_surface=font.render(text,False,color)#render means give (内容 抗锯齿 颜色)
        text_rect=text_surface.get_rect()
        text_rect.midtop=(x,y)
        self.screen.blit(text_surface,text_rect)#surface is a image ,and rect is a place ,we let the surface attach to the rect
    def draw_screen(self):
        #show the sprites
        pygame.mixer.music.load('tension_music.mp3')
        pygame.mixer.music.play(loops=-1)
        self.screen.fill((255,152,140))
        self.draw_text('JUMPY',40,(45,65,150),WIDTH/2,HEIGHT/4)
        self.draw_text('UP TO JUMP',22,BLACK,WIDTH/2,HEIGHT/2)
        self.draw_text('PRESS UP TO BEGIN',33,(150,45,68),WIDTH/2,HEIGHT/3)
        #stop the black screen
        #must be drawn after sprite_shows
        pygame.display.flip()
        self.wait_for_key()
        pygame.mixer.music.fadeout(500)
        pygame.mixer.music.load('one_man_to_buy.mp3')
        pygame.mixer.music.play(loops=1)
        self.last_time = pygame.time.get_ticks()
    def wait_for_key(self):
    #if the process was stuck in a no_show_sprite state the screen_picture will be stopped
        while self.waiting:
            self.clock.tick(30)
            for event in pygame.event.get():
                if event.type==pygame.QUIT:
                    self.waiting=False#the wait must be stopped ,otherwise the self.running=false will not begin to check
                    self.running=False
                    self.playing=False
                if event.type==pygame.KEYUP:#remember KEYUP is a kind of event,just like QUIT ,K_UP must be used in keys[K_UP]
                    self.waiting=False
    def draw_death_screen(self):
        #show the sprites
        pygame.mixer.music.load('death_music.mp3')
        pygame.mixer.music.play(loops=1)
        self.max_record()
        self.screen.fill((255,50,50))
        self.draw_text('GAME OVER',40,(45,65,150),WIDTH/2,HEIGHT/4)
        self.draw_text(f'YOUR SCORE:{self.score}', 22, BLACK, WIDTH / 2, HEIGHT / 2)
        self.draw_text(f'HISTORY RECORD:{self.max_record_number}', 27, BLACK, WIDTH / 2, HEIGHT /2.4)
        self.draw_text('PRESS UP TO CONTINUE',33,(150,45,68),WIDTH/2,HEIGHT/3)
        #stop the black screen
        #must be drawn after sprite_shows
        pygame.display.flip()
        self.waiting = True
        self.wait_for_key()
        pygame.mixer.music.fadeout(500)
    def draw_time(self):
        font=pygame.font.Font(self.font_name,14)
        text_image=font.render(f'time:{round((pygame.time.get_ticks()-self.last_time)/1000,1)}',True,BLACK)
        text_rect=text_image.get_rect()
        text_rect.center=(WIDTH/2,HEIGHT/9)
        self.screen.blit(text_image,text_rect)
    def max_record(self):
        PLANE_RECORD_LIST = []
        with open('PLANE_RECORD', 'r') as file:
            for i in file.read().split('\n'):
                if i != '':
                  PLANE_RECORD_LIST.append(int(i))
        self.max_record_number= str(max(PLANE_RECORD_LIST))
    def load_data(self):
        self.dir=path.dirname(__file__)
        img_dir=path.join(self.dir,'img')
game=Game()
while game.running:
    game=Game()
    while game.playing:
      game.update()
      game.clock.tick(30)
pygame.quit()